
#ifndef _USB_F_DFU_H_
#define _USB_F_DFU_H_

#include "implementation/freebsd_sys.h"
#include "composite.h"

#define USB_DFU_DT_FUNC            0x21
#define USB_DFU_USB_BUFSIZ            4096

#define USB_DFU_BIT_WILL_DETACH        (0x1 << 3)
#define USB_DFU_BIT_MANIFESTATION_TOLERANT    (0x1 << 2)
#define USB_DFU_BIT_CAN_UPLOAD        (0x1 << 1)
#define USB_DFU_BIT_CAN_DNLOAD        0x1

/* The status of Flash upgrade state */
#define DFU_FLASH_STATE_UPGRADING   1
#define DFU_FLASH_STATE_UPGRADED    0
#define DFU_FLASH_STATE_ERROR          2

#define DFU_DETACH        0x00
#define DFU_DNLOAD        0x01
#define DFU_UPLOAD        0x02
#define DFU_GETSTATUS        0x03
#define DFU_CLRSTATUS        0x04
#define DFU_GETSTATE        0x05
#define DFU_ABORT        0x06
#define REQ_DFU_FLASH_STATE 0x07

#define USB_DFU_STATUS_OK            0x00
#define USB_DFU_STATUS_errUNKNOWN        0x0e

#define DFU_RET_STALL            -1
#define DFU_RET_ZLP                0
#define DFU_RET_STAT_LEN            6

enum usb_dfu_state {
    USB_DFU_STATE_appIDLE        = 0,
    USB_DFU_STATE_appDETACH        = 1,
    USB_DFU_STATE_dfuIDLE        = 2,
    USB_DFU_STATE_dfuDNLOAD_SYNC    = 3,
    USB_DFU_STATE_dfuDNBUSY        = 4,
    USB_DFU_STATE_dfuDNLOAD_IDLE    = 5,
    USB_DFU_STATE_dfuMANIFEST_SYNC    = 6,
    USB_DFU_STATE_dfuMANIFEST        = 7,
    USB_DFU_STATE_dfuMANIFEST_WAIT_RST    = 8,
    USB_DFU_STATE_dfuUPLOAD_IDLE    = 9,
    USB_DFU_STATE_dfuERROR        = 10,
};

struct usb_dfu_status {
    u8                bStatus;
    u8                bwPollTimeout[3];
    u8                bState;
    u8                bString;
} __packed;

struct dfu_function_descriptor {
    u8                bLength;
    u8                bDescriptorType;
    u8                bmAttributes;
    u16               wDetachTimeOut;
    u16               wTransferSize;
    u16               bcdDFUVersion;
} __packed;


#define USB_DFU_POLL_TIMEOUT_MASK           (0xFFFFFFUL)
#endif /* _USB_F_DFU_H_ */
